import bpy

import engine.initLIB.load_dll as engineLib
import ctypes

import 节点.Core.bl_UI配色 as UI配色




from bpy.types import Operator
from 全局控制.Node.节点和插座基类.bl_UpdateNode import *
import 全局控制.Node.节点和插座基类.bl_节点基类 as 基类





engineLib.flexCAPI.f_创建取范围内坐标索引节点.restype = ctypes.c_bool


类型枚举 = [
	("TYPE_手动", "手动", "", 0),
	("标识_逐帧", "逐帧", "", 1),
]


class C_SceneNode_物体选择(基类.C_SN_基类):
	bl_dname = 'bl_node_物体选择'
	bl_label = '物体选择'

	#m_方式切换 = bpy.props.EnumProperty(items = 类型枚举, name="更新方式", default="TYPE_手动" )
	#m_帧间隔 = bpy.props.IntProperty(default=1)
	def init(self, context):
		super(C_SceneNode_物体选择, self).f_init(context)
		self.inputs.new('C_NodeSocket_物体', name='物体列表')
		self.inputs.new('C_NodeSocket_i', name='截取索引')
		self.outputs.new('C_NodeSocket_物体', name='选区物体')
		

	def draw_buttons(self, context, layout):
		#self.inputs
		pass

	def f_update(self, 是否向下传递=False, input插座=None):
		key = self.inputs['截取索引'].f_getData()
		obj = self.inputs['物体列表'].f_getData(int(key))
		if obj :
			self.outputs['选区物体'].f_setData(obj)
			#print('物体选择 = ', self.name, input插座)
			super(C_SceneNode_物体选择, self).f_update(是否向下传递, input插座)
		else:
			print('当前索引没有找到物体:', key)
	
class C_NODE_MENU_物体选择(bpy.types.Operator):
	bl_idname = 'node.global_node_intercept_object'
	bl_label = 'Add 物体选择'
	bl_options = {'REGISTER', 'UNDO'}

	def execute(operator, context):
		operator.use_transform = True
		bpy.ops.node.add_node(type='C_SceneNode_物体选择', use_transform=True)
		return {'FINISHED'}





class C_SceneNode_取物体所在列表中位置(基类.C_SN_基类):
	bl_dname = 'bl_node_取物体所在列表中位置'
	bl_label = '取物体所在列表中位置'

	def init(self, context):
		super(C_SceneNode_取物体所在列表中位置, self).f_init(context)
		self.inputs.new('C_NodeSocket_物体', name='物体列表')
		self.inputs.new('C_NodeSocket_物体', name='要取物体')

		self.outputs.new('C_NS_List_T', name='列表索引')
		self.outputs['列表索引'].f_set维度(0)

	def f_update(self, 是否向下传递=False, input插座=None):
		out = self.outputs['列表索引']
		#out.f_clear()
		objs = self.inputs['物体列表'].f_getData()
		目标物体 = self.inputs['要取物体'].f_getData()

		if 目标物体 == None or objs == None : return
		#print('要取物体:', self.inputs['要取物体'].f_getData())
		找到的物体ID = []
		for 要找物体 in self.inputs['要取物体'].f_getData():
			index = 0
			for obj in objs :
				#print('---- obj --- ', obj, objs, 要找物体)
				if obj.name == 要找物体.name :
					找到的物体ID.append(index)
					break
				index += 1

		#print('要找物体 = ', 找到的物体ID)
		out.f_setData(找到的物体ID)
		super(C_SceneNode_取物体所在列表中位置, self).f_update(是否向下传递, input插座)

class C_NODE_MENU_取物体所在列表中位置(bpy.types.Operator):
	bl_idname = 'node.global_node_obj_list_index'
	bl_label = '取物体所在列表中位置'
	bl_options = {'REGISTER', 'UNDO'}

	def execute(operator, context):
		bpy.ops.node.add_node(type='C_SceneNode_取物体所在列表中位置', use_transform=True)
		return {'FINISHED'}






class C_SceneNode_取列表中索引所在物体(基类.C_SN_基类):
	bl_dname = 'bl_node_取列表中索引所在物体'
	bl_label = '取列表中索引所在物体'

	def init(self, context):
		super(C_SceneNode_取列表中索引所在物体, self).f_init(context)
		self.inputs.new('C_NodeSocket_物体', name='物体列表')
		self.inputs.new('C_NS_List_T', name='列表索引')
		
		self.outputs.new('C_NodeSocket_物体', name='取得物体')
		self.inputs['列表索引'].f_set维度(0)

	def f_update(self, 是否向下传递=False, input插座=None):
		objs = self.inputs['物体列表'].f_getData()
		ids = self.inputs['列表索引'].f_getData()
		#print('找到的物体 = :', 'ids:', ids)
		物体数量 = len(objs)
		找到的物体 = []
		for index in ids :
			if index < 物体数量:
				找到的物体.append(objs[index])
		#print('找到的物体 = :', 找到的物体, 物体数量, 'ids:', ids)
		self.outputs['取得物体'].f_setData(找到的物体)
		super(C_SceneNode_取列表中索引所在物体, self).f_update(是否向下传递, input插座)

class C_NODE_MENU_取列表中索引所在物体(bpy.types.Operator):
	bl_idname = 'node.global_node_get_list_index_obj'
	bl_label = '取列表中索引所在物体'
	bl_options = {'REGISTER', 'UNDO'}
	
	def execute(operator, context):
		bpy.ops.node.add_node(type='C_SceneNode_取列表中索引所在物体', use_transform=True)
		return {'FINISHED'}























def f_update_取范围索引排除已选(self, context):
	data = [list(self.m_是否排除已选索引)]
	engineLib.flexCAPI.f_node_传入BL数据(ctypes.c_wchar_p(self.id_data.name), ctypes.c_wchar_p(self.name), ctypes.py_object(data));


class C_Node_取范围内坐标索引(基类.C_Node_基类):
	bl_dname = 'bl_node_取范围内坐标索引'
	bl_label = '取范围内坐标索引'

	m_是否排除已选索引 = bpy.props.BoolProperty(update=f_update_取范围索引排除已选)
	def init(self, context):
		super(C_Node_取范围内坐标索引, self).f_init(context)
		self.inputs.new('C_Socket_Vec3_Array1D', name='坐标')
		self.inputs.new('C_Socket_Vec3_Array1D', name='中点')
		self.inputs.new('C_Socket_F32', name='范围')
		self.inputs.new('C_Socket_F32', name='重置时间')
		
		self.outputs.new('C_Socket_I32_Array1D', name='索引')
		self.f_toCPP()

		self.use_custom_color = True
		self.color = UI配色.g_内部节点颜色

	def f_toCPP(self):
		是否更新 = engineLib.flexCAPI.f_创建取范围内坐标索引节点(ctypes.c_wchar_p(self.id_data.name), ctypes.c_wchar_p(self.name), self.f_getPyObject());
		if 是否更新 :
			self.inputs['范围'].f_update()
			self.inputs['重置时间'].f_update()

	def draw_buttons(self, context, layout):
		layout.prop(self, 'm_是否排除已选索引')
		

class C_NODE_MENU_取范围内坐标索引(bpy.types.Operator):
	bl_idname = 'node.global_node_get_get_area_coord_index'
	bl_label = '取范围内坐标索引'
	bl_options = {'REGISTER', 'UNDO'}
	def execute(operator, context):
		bpy.ops.node.add_node(type='C_Node_取范围内坐标索引', use_transform=True)
		return {'FINISHED'}







classes = (
	C_SceneNode_物体选择,
	C_NODE_MENU_物体选择,

	C_SceneNode_取物体所在列表中位置,
	C_NODE_MENU_取物体所在列表中位置,

	C_SceneNode_取列表中索引所在物体,
	C_NODE_MENU_取列表中索引所在物体,



	C_Node_取范围内坐标索引,
	C_NODE_MENU_取范围内坐标索引,

)

def register():
	for c in classes:
		bpy.utils.register_class(c)
		

def unregister():
	for c in classes:
		bpy.utils.unregister_class(c)

